﻿package Classes.Objects 
{
	import Box2D.Dynamics.Contacts.b2Contact;
	import Classes.core.World;
	import Classes.Main;
	import flash.display.MovieClip;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import flash.ui.Keyboard;
	import Box2D.Dynamics.b2ContactListener;
	/**
	 * ...
	 * @author ...
	 */
	public class PhysicsObject
	{
		/****************************************
		* Variáveis visíveis no Level Architect *
		****************************************/
		
		[Property(value = "100")]
		public var width:Number = 100;
		
		[Property(value = "100")]
		public var height:Number = 100;
		
		//Essa variável deve segurar o nome na biblioteca que segura as artes do jogo, encontrada no Main
		[Property(value = "texto")]
		public var stringMovieClip:String = "texto";
		
		//Essa variável serve para dizer se o corpo é estático ou não
		//Corpos estáticos não se movem.
		[Property(value = "true")]
		public var isStatic:Boolean = true;
		
		[Property(value = "0")]
		public var rotation:Number = 0;
		
		[Property(value = "1")]
		public var group:int = 1;
		
		[Property(value = "0")]
		public var offsetX:Number = 0;
		
		[Property(value = "0")]
		public var offsetY:Number = 0;
		
		
		/*************************
		* Variáveis Encapculadas *
		*************************/
		
		private var _x:Number = 0;
		private var _y:Number = 0;
		private var _visible:Boolean = true;
		
		
		/*********************
		* Variáveis Privadas *
		*********************/
		
		//Fator de escala, pixel por metros.
		private var scaleFactor:Number;
		
		
		/*********************
		* Variáveis Públicas *
		*********************/
		
		//Essas duas variáveis são as mais importantes dessa classe
		//A body segura a box do objeto
		//A art segura o MovieClip da arte
		public var body: b2Body;
		public var art: MovieClip;
		
		
		public var maxVelocity: Number = 12;
		
		
		
		public function PhysicsObject(world: World, isStatic:Boolean, x: Number, y: Number, width: Number, height: Number, artName: String, rotation:Number) 
		{
			//Criar gameart
			art = new Main._stringsMovieclipsDictionary[artName]();
			art.width = width;
			art.x = x;
			art.y = y;
			art.height = height;
			art.rotation = rotation;
			
			//Salva o fator de escala no próprio objeto.
			this.scaleFactor = world.scaleFactor;
			
			//Criação da box
			var bodyDef:b2BodyDef = new b2BodyDef();
			bodyDef.position.Set(x / scaleFactor, y / scaleFactor);
			if(!isStatic)
				bodyDef.type = b2Body.b2_dynamicBody;
			body = world.CreateBody(bodyDef);
			if (body != null)
				body.SetAngle(rotation * Math.PI / 180);
			var shape:b2PolygonShape = new b2PolygonShape();
			shape.SetAsBox(width / 2 / scaleFactor, height / 2 / scaleFactor);
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			fixtureDef.shape = shape;
			fixtureDef.density = 1;
			fixtureDef.friction = 0.6;
			fixtureDef.restitution = 0;
			var fixture:b2Fixture = body.CreateFixture(fixtureDef);
			
			
			//Adiciona a gameArt na tela
			Main.getInstance().MC_tela.addChild(art);
			
			//wheelArray.push(wheelBody);

		}
		
		public function update():void
		{
			if (art)
			{
				art.x = body.GetPosition().x * scaleFactor;
				art.y = body.GetPosition().y * scaleFactor;
				//art.rotation = 
			}	
		}
		
		/*
		 * Não acho que seja necessário essas funções
		 * 
		[Property(value="", browse="true")]
		public function set view(value:*):void
		{
			//_view = value;
		}
		
		[Property(value="topLeft")]
		public function set registration(value:String):void
		{
			//_registration = value;
		}
		*/
		
		public function get visible():Boolean
		{
			return _visible;
		}
		
		public function set visible(value:Boolean):void
		{
			_visible = value;
			
			if (art)
				art.visible = _visible;
		}
		
		public function get x():Number
		{
			if (body)
				return body.GetPosition().x * scaleFactor;
			else
				return _x * scaleFactor;
		}
		
		[Property(value="0")]
		public function set x(value:Number):void
		{
			_x = value / scaleFactor;
			
			if (body)
			{
				var pos:b2Vec2 = body.GetPosition();
				pos.x = _x;
				body.SetTransform(new b2Transform(pos));
			}
		}
			
		public function get y():Number
		{
			if (body)
				return body.GetPosition().y * scaleFactor;
			else
				return _y * scaleFactor;
		}
		
		[Property(value="0")]
		public function set y(value:Number):void
		{
			_y = value / scaleFactor;
			
			if (body)
			{
				var pos:b2Vec2 = body.GetPosition();
				pos.y = _y;
				body.SetTransform(new b2Transform(pos));
			}
		}
		
		public function destroy():void
		{
			body.DestroyFixture();
			Main.getInstance().MC_tela.removeChild(art);
		}
		
		public virtual function BeginContact(contact:b2Contact):void { }
		public virtual function EndContact(contact:b2Contact):void { }
	}

}